import { go } from '@/assets/js/go';
import { Message } from 'element-ui';
let G = go.GraphObject.make; //GOJS对象
// 选中节点的边框样式
function makeNodeSelectionAdornmentTemplate() {
  return G(
    go.Adornment,
    'Auto',
    G(go.Shape, {
      fill: null,
      // fill: '#00bfff69',
      stroke: 'deepskyblue',
      strokeWidth: 2,
      strokeDashArray: [4, 2]
    }),
    G(go.Placeholder)
  );
}

// 悬浮在某一个图标上提示信息/tooltip上显示的信息
function makeTooltipTemplate() {
  return G(
    go.Adornment,
    go.Panel.Auto,
    G(go.Shape, 'RoundedRectangle', {
      fill: 'whitesmoke',
      stroke: 'gray'
    }),
    G(
      go.TextBlock,
      {
        margin: 5,
        editable: true
      },
      new go.Binding('text', '', function (data) {
        if (data.text !== undefined) return data.text;
        return '(未命名)';
      })
    )
  );
}
// 连接线的选中样式，线条中文本的选中样式
function makeLinkSelectionAdornmentTemplate() {
  return G(
    go.Adornment,
    'Link',
    G(go.Shape, {
      isPanelMain: true,
      fill: null,
      stroke: '#1E90FF',
      strokeWidth: 0
    }),
    G(
      go.TextBlock,
      {
        textAlign: 'center',
        font: '10pt helvetica, arial, sans-serif',
        stroke: 'blue',
        margin: 2
      },
      new go.Binding('text', 'text')
    )
  );
}
function hasStartAndEndNodeFn(routeJson) {
  let hasStartNode = routeJson.nodeDataArray.find((node) => node.category == 'Start');
  let hasEndNode = routeJson.nodeDataArray.find((node) => node.category == 'End');
  let startNode = routeJson.linkDataArray.filter((data) => {
    return (data.from + '').indexOf('Start') > -1;
  });
  let endNode = routeJson.linkDataArray.filter((data) => {
    return (data.to + '').indexOf('End') > -1;
  });
  if (!hasStartNode) {
    Message.warning(`缺少开始，请重新配置工艺路线`);
    return false;
  }

  if (startNode.length === 0) {
    Message.error('没有连接开始节点');
    return false;
  } else if (startNode.length > 1) {
    Message.error('存在多个连接开始节点');
    return false;
  } else if (startNode[0].to === 'End') {
    Message.error('开始节点不能直接连接结束节点');
    return false;
  }

  if (!hasEndNode) {
    Message.warning(`缺少结束，请重新配置工艺路线`);
    return false;
  }
  if (endNode.length === 0) {
    Message.error('没有连接结束节点');
    return false;
  } else if (endNode.length > 1) {
    Message.error('存在多个连接结束节点');
    return false;
  }
  return true;
}

export function hasRepeatNodeFn(routeJson) {
  let flagArray = [],
    flagRepeat = false,
    repeatStation = '';
  routeJson.nodeDataArray.forEach((item) => {
    if (flagArray[item.category]) {
      flagRepeat = true;
      repeatStation = item.text;
    }
    flagArray[item.category] = true;
  });
  if (flagRepeat) {
    Message.warning(`${repeatStation}工站重复，请删除其中一个`);
    return false;
  }
  return true;
}

function checkConnectLine(linkDataArray, nodeInfoList = []) {
  let checkConnectLineStatus = nodeInfoList.every((node) => {
    return linkDataArray.map((link) => link.from).includes(node.key) || linkDataArray.map((link) => link.to).includes(node.key);
  });
  if (!checkConnectLineStatus) {
    Message.warning('获取不到配置连接工站');
    return false;
  }
  return true;
}

function hasSkipNodeFn(nodeInfoList) {
  // 查找所有首尾工单工段工序
  let firstAndLastWorkRoutes = nodeInfoList.filter((node) => {
    return node.isFirst || node.isFirstInSection || node.isLast || node.isLastInSection;
  });

  let isSkippableNode = firstAndLastWorkRoutes.every((node) => {
    return !node.isSkippable;
  });
  if (!isSkippableNode) {
    Message.error('工单和工段的首尾工序，不可开启可跳！');
    return false;
  }
  return true;
}
function hasPackCheckNodeFn(nodeInfoList) {
  let nodePackType = nodeInfoList.filter((node) => {
    return node.routeType == 'PACKING';
  });
  let packCheck = nodePackType.find((node) => {
    let processRouteConfigDTOList = node.processRouteConfigDTOList;
    let find = processRouteConfigDTOList.find((item) => item.key == 'productPackingConfigId');
    return !find.value;
  });

  if (packCheck) {
    Message.error(`${packCheck.routeName}工站必须设置包装规则！`);
    return false;
  }
  return true;
}
function hasAgingCheckNodeFn(nodeInfoList) {
  let agingCheck = nodeInfoList
    .filter((node) => {
      return node.routeType == 'AGING';
    })
    .find((node) => {
      let processRouteConfigDTOList = node.processRouteConfigDTOList;
      let agingTime = processRouteConfigDTOList.find((item) => item.key == 'agingTime');
      let agingAlertTime = processRouteConfigDTOList.find((item) => item.key == 'agingAlertTime');
      return !agingTime.value || !agingAlertTime.value;
    });
  if (agingCheck) {
    Message.error(`${agingCheck.routeName}工站必须设置老化时间和老化预警时间！`);
    return false;
  }
  return true;
}
function hasAgingTimeCheckNodeFn(nodeInfoList) {
  let agingTimeCheck = nodeInfoList
    .filter((node) => {
      return node.routeType == 'AGING';
    })
    .find((node) => {
      let processRouteConfigDTOList = node.processRouteConfigDTOList;
      let agingTime = processRouteConfigDTOList.find((item) => item.key == 'agingTime');
      let agingAlertTime = processRouteConfigDTOList.find((item) => item.key == 'agingAlertTime');
      return Number(agingAlertTime.value) > Number(agingTime.value);
    });
  if (agingTimeCheck) {
    Message.error(`${agingTimeCheck.routeName}工站老化预警时间不能大于老化时间！`);
    return false;
  }
  return true;
}

function hasAgingProportionCheckNodeFn(nodeInfoList) {
  let agingProportionCheck = nodeInfoList
    .filter((node) => {
      return node.routeType == 'AGING';
    })
    .find((node) => {
      let processRouteConfigDTOList = node.processRouteConfigDTOList;
      let agingProportion = processRouteConfigDTOList.find((item) => item.key == 'agingProportion');
      const num = Number(agingProportion.value);
      return agingProportion.value != '' && Number.isInteger(num) && (num < 1 || num > 100);
    });
  if (agingProportionCheck) {
    Message.error(`${agingProportionCheck.routeName}工站老化比例必须在1-100的区间！`);
    return false;
  }
  return true;
}

function isConfigAssemblyMaterial(nodeInfoList) {
  let assemblyStations = nodeInfoList.filter((node) => {
    return node.routeType == 'ASSEMBLY';
  });
  if (assemblyStations && assemblyStations.length > 0) {
    let status = assemblyStations.find((node) => {
      return !node.assembleKeyMaterialConfigList || node.assembleKeyMaterialConfigList.length == 0;
    });
    if (status) {
      Message.error(`${status.routeName}工站必须配置关键物料信息！`);
      return false;
    }
  }
  return true;
}

function checkBadStandardFrequency(nodeInfoList) {
  let nodeList = nodeInfoList.filter((node) => {
    return node.routeType == 'TEST';
  });
  let testCheck = nodeList.find((node) => {
    let processRouteConfigDTOList = node.processRouteConfigDTOList;
    let NgTime = processRouteConfigDTOList.find((item) => item.key == 'NgTime');
    return !NgTime.value;
  });

  if (testCheck) {
    Message.error(`${testCheck.routeName}工站必须设置不良次数！`);
    return false;
  }
  let reg = /^[1-9]\d*$/g;
  for (let i = 0; i < nodeList.length; i++) {
    let processRouteConfigDTOList = nodeList[i].processRouteConfigDTOList;
    let NgTime = processRouteConfigDTOList.find((item) => item.key == 'NgTime');
    reg.lastIndex = 0;
    if (NgTime && !reg.test(NgTime.value)) {
      Message.error(`${nodeList[i].routeName}中的不良标准次数不能小于1，且为整数！`);
      return false;
    }
  }
  return true;
}

export let goDesigner = (params) => {
  let { dom, isReadOnly } = params;
  let designer = G(go.Diagram, dom, {
    //设计框中网格样式
    grid: G(
      go.Panel,
      'Grid',
      G(go.Shape, 'LineH', {
        stroke: 'lightgray',
        strokeWidth: 0.5
      }),
      G(go.Shape, 'LineH', {
        stroke: 'gray',
        strokeWidth: 0.5,
        interval: 10
      }),
      G(go.Shape, 'LineV', {
        stroke: 'lightgray',
        strokeWidth: 0.5
      }),
      G(go.Shape, 'LineV', {
        stroke: 'gray',
        strokeWidth: 0.5,
        interval: 10
      })
    ),
    isReadOnly,
    initialContentAlignment: go.Spot.Center, //初始位置在中间，若设置则"modelData": {"position":"-5 -5"},
    allowDrop: true, // must be true to accept drops from the Palette
    allowTextEdit: false, //允许文本编辑
    allowHorizontalScroll: true, //允许水平滑动
    allowVerticalScroll: true, //允许垂直滑动
    click: function (e, obj) {},
    'toolManager.mouseWheelBehavior': go.ToolManager.WheelZoom, //允许轮滑滚动
    'draggingTool.dragsLink': false, //线条是否可以拖拽
    'draggingTool.isGridSnapEnabled': true,
    'linkingTool.isUnconnectedLinkValid': false, //是否可以放置不连接的线
    'linkingTool.portGravity': 20,
    'relinkingTool.isUnconnectedLinkValid': false, //拖动之后可以放置不连接的线
    'relinkingTool.portGravity': 20,
    'relinkingTool.fromHandleArchetype': G(go.Shape, 'Diamond', {
      segmentIndex: 0,
      cursor: 'pointer',
      desiredSize: new go.Size(8, 8),
      fill: 'tomato',
      stroke: 'darkred'
    }),
    'relinkingTool.toHandleArchetype': G(go.Shape, 'Diamond', {
      segmentIndex: -1,
      cursor: 'pointer',
      desiredSize: new go.Size(8, 8),
      fill: 'darkred',
      stroke: 'tomato'
    }),
    'linkReshapingTool.handleArchetype': G(go.Shape, 'Diamond', {
      desiredSize: new go.Size(7, 7),
      fill: 'lightblue',
      stroke: 'deepskyblue'
    }),
    'undoManager.isEnabled': true
  });

  return {
    designer,
    makeNodeSelectionAdornmentTemplate,
    makeTooltipTemplate,
    makeLinkSelectionAdornmentTemplate
  };
};
// 获取流程图数据
export const getFlowData = (designer) => {
  designer.model.modelData.position = go.Point.stringify(designer.position);
  return designer.model.toJson();
};

export const verifyNodeFn = (routeJson, nodeInfoList) => {
  let fns = [hasStartAndEndNodeFn(routeJson), checkConnectLine(routeJson.linkDataArray, nodeInfoList)];
  return fns.every((fn) => fn);
};

export const verifyStationFn = (nodeInfoList) => {
  let fns = [
    () => hasSkipNodeFn(nodeInfoList),
    () => hasPackCheckNodeFn(nodeInfoList),
    () => hasAgingCheckNodeFn(nodeInfoList),
    () => hasAgingTimeCheckNodeFn(nodeInfoList),
    () => hasAgingProportionCheckNodeFn(nodeInfoList),
    () => isConfigAssemblyMaterial(nodeInfoList),
    () => checkBadStandardFrequency(nodeInfoList)
  ];
  return fns.every((fn) => fn());
};

export const checkArrayRepeatData = (data) => {
  let setDataLen = [...new Set(data)].length;
  if (data.length > setDataLen) {
    return true;
  } else {
    return false;
  }
};
// 不会出现开始连接多个工序的情况
export const resetOrder = (json) => {
  try {
    let linkDataArray = json.linkDataArray;
    let nodeDataArray = json.nodeDataArray;
    let newNodeDataArray = nodeDataArray.filter((node) => node.key == 'Start' || node.key == 'End');
    let startNode = linkDataArray.filter((data) => data.from == 'Start');
    let startNodeTo = null;
    let nextNode = null;
    if (startNode && startNode.length > 0) {
      startNodeTo = startNode[0].to;
      if (startNodeTo != 'End') {
        nextNode = nodeDataArray.find((node) => node.key && node.key == startNodeTo);
        if (nextNode) newNodeDataArray.push(nextNode);
      }
    }
    if (nextNode) {
      let newNodeList = order(nextNode.key, newNodeDataArray);
      function order(nextNodeKey, node) {
        let nextNode = linkDataArray.filter((data) => data.from == nextNodeKey);
        let nextNodeTo = null;
        if (nextNode && nextNode.length > 0) {
          nextNodeTo = nextNode[0].to;
          if (nextNodeTo != 'End') {
            let nextData = nodeDataArray.find((node) => node.key && node.key == nextNodeTo);
            if (nextData) node.push(nextData);
            order(nextData.key, node);
          }
        }
        return node;
      }
      json.nodeDataArray = newNodeList;
    }
    return json;
  } catch (error) {
    console.log(error);
  }
};

// 初始化拖拽出来的工序信息
export const initStationInfo = (partData, check) => {
  let currentStationInfo = {};
  currentStationInfo.key = partData.key;
  let condition;
  if (check) {
    condition = !$('#' + partData.key).val() && partData.category !== 'Start' && partData.category !== 'End';
  } else {
    condition = partData.category !== 'Start' && partData.category !== 'End';
  }
  if (condition) {
    currentStationInfo.workstationId = partData.category;
    currentStationInfo.routeName = partData.text;
    currentStationInfo.workSectionColor = partData.workSectionColor;
    ['workSectionId', 'workSectionName', 'code', 'routeType', 'imgsrc'].map((item) => (currentStationInfo[item] = partData[item]));
    ['isFirst', 'isLast', 'isSkippable', 'isFirstInSection', 'isLastInSection'].map((item) => (currentStationInfo[item] = false));

    if (currentStationInfo.routeType == 'OVERSTATION') {
      currentStationInfo.processRouteConfigList = [
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'isDeduct',
          value: ''
        },
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'deductType',
          value: ''
        }
      ];
    } else if (currentStationInfo.routeType == 'AGING') {
      currentStationInfo.processRouteConfigList = [
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'agingTime',
          value: ''
        },
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'agingAlertTime',
          value: ''
        },
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'agingProportion',
          value: 100
        }
      ];
    } else if (currentStationInfo.routeType == 'TEST') {
      currentStationInfo.processRouteConfigList = [
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'NgTime',
          value: ''
        }
      ];
    } else if (currentStationInfo.routeType == 'PACKING') {
      currentStationInfo.processRouteConfigList = [
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'productPackingConfigId',
          value: ''
        },
        {
          routeType: currentStationInfo.routeType,
          routeName: currentStationInfo.routeName,
          key: 'productPackingConfigName',
          value: ''
        }
      ];
    } else if (currentStationInfo.routeType == 'ASSEMBLY') {
      currentStationInfo.assembleKeyMaterialConfigList = [];
      currentStationInfo.processRouteConfigList = [];
    } else {
      // 其余类型的工站
      currentStationInfo.processRouteConfigList = [];
    }
  }
  // currentStationInfo['sectionColor'] = 'blue';
  // currentStationInfo['workSectionColor'] = partData.workSectionColor;
  // currentStationInfo['rectVisible'] = true;
  return currentStationInfo;
};

// 确定isFirstInSection和isLastInSection
export const markSectionPosition = (nodeInfoList, sections) => {
  const sectionInfo = {};
  // 构建工段信息对象
  sections.forEach((section) => {
    const sectionId = section.sectionId;
    sectionInfo[sectionId] = {
      list: nodeInfoList.filter((node) => node.workSectionId === sectionId)
    };
  });

  // 标记工段位置
  sections.forEach((section) => {
    const sectionId = section.sectionId;
    const sectionNodes = sectionInfo[sectionId].list;

    if (sectionNodes.length === 1) {
      const node = sectionNodes[0];
      node.isFirstInSection = true;
      node.isLastInSection = true;
    } else {
      sectionNodes.forEach((node, i) => {
        node.isFirstInSection = i === 0;
        node.isLastInSection = i === sectionNodes.length - 1;
      });
    }
  });

  return nodeInfoList;
};

// 验证工段顺序
export const verifySectionOrder = (nodeInfoList, sections) => {
  for (let i = 0; i < nodeInfoList.length; i++) {
    let seqOne, seqTwo;
    let findWorkSection = sections.filter((item) => item.sectionId === nodeInfoList[i].workSectionId);
    if (findWorkSection.length > 0) {
      seqOne = findWorkSection[0].sectionSequence;
    }
    for (let j = i + 1; j < nodeInfoList.length; j++) {
      if (nodeInfoList[j].workSectionId) {
        let findWorkSectionTwo = sections.filter((item) => item.sectionId === nodeInfoList[j].workSectionId);
        if (findWorkSectionTwo.length > 0) {
          seqTwo = findWorkSectionTwo[0].sectionSequence;
        }
        if (Number(seqOne) > Number(seqTwo)) {
          Message.error('工艺路线中工站顺序未按生产工段顺序连接，请修改后保存！');
          return false;
        }
      }
    }
  }
  return true;
};

/**
 * 返回处理后的节点信息列表
 *
 * @param {Object} data - 包含节点数据
 * @param {Array} sections - 工段信息数组
 * @param {Array} allActiveStations - 所有活动工站的数组
 * @param {Boolean} isAlreadyConfig - 标记是否已经配置过
 * @param {Boolean} isGdEditorPage - 标记是否在编辑页面
 * @returns {Array} 处理后的节点信息列表
 *
 * 该函数根据提供的节点数据、工段信息、工站信息等参数，生成并返回一个包含节点详细信息的列表，
 * 同时根据工段信息标记每个节点在其所属工段中的位置（是否是第一个或最后一个节点）。
 */
export const returnNodeInfoList = (data, sections, allActiveStations, isAlreadyConfig, isGdEditorPage) => {
  let nodeList = data
    .filter((node) => node.category !== 'Start' && node.category !== 'End')
    .map((node, index, array) => {
      const sameData =
        allActiveStations.find((all) => {
          return all.workstationId === (node.workstationId || node.id);
        }) || {};
      let data = {
        id: isAlreadyConfig ? sameData.id || '' : '',
        key: node.key,
        processType: isGdEditorPage ? 'WORKORDER' : 'PART',
        workstationId: node.workstationId || node.id,
        routeType: node.routeType,
        routeCode: node.routeCode || node.code,
        routeName: node.routeName || node.name,
        imgsrc: node.imgsrc,
        location: node.location,
        sequence: index,
        workSectionId: node.workSectionId,
        isFirst: index === 0,
        isLast: index === array.length - 1,
        isSkippable: sameData.isSkippable,
        status: node.status,
        workSectionName: node.workSectionName,
        assembleKeyMaterialConfigList: sameData.assembleKeyMaterialConfigList || [],
        processRouteConfigDTOList: sameData.processRouteConfigList || []
      };
      return data;
    });
  return markSectionPosition(nodeList, sections);
};
